﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.ServiceModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Bookvar.ApplicationModel;
using Bookvar.ObjectModel.Collections;
using Bookvar.ServiceModel;
using Bookvar.Web;
using BookvarWpf.Properties;
using LocalizationResources = Bookvar.UI.Localization.Resources;

namespace BookvarWpf.Windows
{
    /// <summary>
    /// Interaction logic for SampleWindow.xaml
    /// </summary>
    public partial class PublishMap
    {
        //private readonly AttachmentCollection attachments;
        private readonly string defaultList;
        private readonly SharePointService sharePointService;
        private string fileName;
        private string fileToPublish;

        public PublishMap( string fileToPublish )
            : this( fileToPublish, Path.GetFileName( fileToPublish ) )
        {
        }

        public PublishMap( string fileToPublish, string fileName )
        {
            InitializeComponent();
            sharePointService = new SharePointService( Settings.Default.SiteAddress, Settings.Default.Username,
                                                       Settings.Default.Password, Settings.Default.Domain );
            defaultList = Settings.Default.DefaultMOSSList;
            OnLoadingStart();
            var workerThread = new Thread( ExecuteLoadLists );
            workerThread.Start();
            this.fileToPublish = fileToPublish;
            txtFileName.Text = fileName;
            listNames.SelectionChanged += listNames_SelectionChanged;
        }

        public string FileToPublish
        {
            get { return fileToPublish; }
            set { fileToPublish = value; }
        }

        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }

        protected static IErrorService ErrorService
        {
            get { return BookvarApplication.Current.ServiceLayer.GetService<IErrorService>(); }
        }

        private void listNames_SelectionChanged( object sender, SelectionChangedEventArgs e )
        {
            bool showTagsPanel = false;
            TagCollection tagCollection = null;
            foreach ( WssList wssList in e.AddedItems )
            {
                if ( wssList.HasTags )
                {
                    showTagsPanel = true;
                    tagCollection = wssList.TagCollection;
                    break;
                }
            }
            if ( showTagsPanel )
            {
                tagsPanel.Visibility = Visibility.Visible;
                TagCloudControl.TagsCollection = tagCollection;
                TagCloudControl.ClearSelection();
                txtTags.Text = string.Empty;
            }
            else
            {
                tagsPanel.Visibility = Visibility.Hidden;
            }
        }

        protected void OnLoadingStart()
        {
            progressAnimation.Start();
        }

        protected void OnLoadingStop()
        {
            progressAnimation.Stop();
        }

        private void PopulateListNames( List<WssList> wssLists )
        {
            OnLoadingStop();

            listsPanel.Visibility = Visibility.Visible;
            listNames.Items.Clear();
            foreach ( WssList wssList in CheckForDefault( wssLists ) )
            {
                listNames.Items.Add( wssList );
            }
            if ( listNames.Items.Count > 0 )
            {
                listNames.SelectedIndex = 0;
            }
        }

        private List<WssList> CheckForDefault( List<WssList> wssLists )
        {
            WssList defaultWssList = null;

            foreach ( WssList wssList in wssLists )
            {
                if ( wssList.Name == defaultList )
                {
                    defaultWssList = wssList;
                    break;
                }
            }

            if ( defaultWssList != null )
            {
                var result = new List<WssList>();
                result.Add( defaultWssList );
                return result;
            }

            return wssLists;
        }

        private void ExecuteLoadLists()
        {
            try
            {
                List<WssList> lists = sharePointService.GetAllLists();
                listNames.Dispatcher.BeginInvoke( DispatcherPriority.DataBind,
                                                  new PublishMapDelegate( PopulateListNames ),
                                                  lists );
            }
            catch ( CommunicationException ex )
            {
                ex.ToString();
                Dispatcher.BeginInvoke( DispatcherPriority.Normal,
                                        new ShowConnectionErrorDelegate( ShowConnectionError ) );
            }
        }

        private void ShowConnectionError()
        {
            ErrorService.ShowError( LocalizationResources.ErrorNoConnectionWhilePublishing );
            Close();
        }

        private void OnPublishClicked( object sender, RoutedEventArgs e )
        {
            var selectedList = listNames.SelectedItem as WssList;
            if ( selectedList == null )
                return;

            string listName = selectedList.Name;
            fileName = txtFileName.Text.Trim();
            listNames.IsEnabled = false;
            if ( !String.IsNullOrEmpty( listName ) )
            {
                OnLoadingStart();
                string fileRef = string.Format( CultureInfo.CurrentCulture, "http://{0}/{1}/{2}",
                                                Settings.Default.SiteAddress, listName, fileName );
                var webClient = new WebClient();
                webClient.Credentials =
                    new NetworkCredential( Settings.Default.Username, Settings.Default.Password,
                                           Settings.Default.Password );
                var stream = new FileStream( fileToPublish, FileMode.Open, FileAccess.Read );
                var content = new byte[stream.Length];
                stream.Read( content, 0, content.Length );
                webClient.UploadDataCompleted += WebClient_UploadDataCompleted;
                webClient.UploadDataAsync( new Uri( fileRef ), "PUT", content );
            }
        }

        private void WebClient_UploadDataCompleted( object sender, UploadDataCompletedEventArgs e )
        {
            var selectedList = listNames.SelectedItem as WssList;
            if ( selectedList == null )
                return;

            string listName = selectedList.Name;
            string tags = txtTags.Text.Trim();
            if ( !string.IsNullOrEmpty( tags ) )
            {
                sharePointService.UpdateTags( listName, fileName, tags );
            }
            OnLoadingStop();
            CloseCommand.Execute( null, this );
        }

        private void TagCloudControl_TagSelectionChanged( object sender, RoutedEventArgs e )
        {
            var filter = e.OriginalSource as string;
            string tags = txtTags.Text.Trim();
            var tagList = new List<string>();
            if ( !string.IsNullOrEmpty( tags ) )
            {
                string[] tagsArray =
                    tags.Split( new[] { SharePointService.TagsSeparator }, StringSplitOptions.RemoveEmptyEntries );
                tagList.AddRange( tagsArray );
            }
            tagList.Add( filter );
            txtTags.Text = string.Join( SharePointService.TagsSeparator, tagList.ToArray() );
        }

        #region Nested type: PublishMapDelegate

        private delegate void PublishMapDelegate( List<WssList> lists );

        #endregion

        #region Nested type: ShowConnectionErrorDelegate

        private delegate void ShowConnectionErrorDelegate();

        #endregion
    }
}